#include "widget5.h"
#include <QDebug>
#include <cmath>
#include <QtGui/QPainterPath>

#define PI 3.14
Widget5::Widget5(QWidget *parent) : QWidget(parent)
{
    setPalette(QPalette(QColor(0, 200, 100))); //设置背景颜色
    init();
}
Widget5::~Widget5(){
    delete pen;
    delete brush;
    delete line;
}
//初始化
void Widget5::init(){
    setWindowTitle("绘图");
    setGeometry(300, 100, 800, 600);
    brush =  new QBrush(); //画刷
    brush->setStyle(Qt::BrushStyle::NoBrush);

    pen = new QPen(); //画笔


    //直线
    line = new  QLine(100, 100, 200, 100);

}
//QPainter的内存分配也必须在Widget::paintEvent(QPaintEvent *event)函数中进行
void Widget5::paintEvent(QPaintEvent *){
    qDebug()<< "绘制函数";
   paintSomething();

   // 绘制koch线
    //doExercise();

}
//绘制图形
void Widget5::paintSomething(){
    QPainter painter(this);
    pen->setColor(QColor(255, 0, 0));
    pen->setWidth(3);
    painter.setPen(*pen);
    painter.setBrush(*brush);

    //绘制直线
    painter.drawLine(*line);
    //绘制矩形
    painter.drawRect(100, 200, 100, 80);
    //圆角矩形
    painter.drawRoundedRect(250, 200, 100, 80, 45, 45);
    //椭圆
    painter.drawEllipse(400, 100, 100, 60);
    //多边形
    QPoint points[3];
    points[0] = QPoint(300, 0);
    points[1] = QPoint(300, 100);
    points[2] = QPoint(400, 100);
    painter.drawPolygon(points, 3);

    //点
    painter.drawPoint(200, 10);
    //弧 后两个参数定义圆的样式 0为起始角度（实际单位为1/16度）
    painter.drawArc(520, 200, 100, 100, 0, 180 * 16);

    //多条线
    QPoint linePoints[4];
    linePoints[0] = QPoint(500, 10);
    linePoints[1] = QPoint(500, 100);
    linePoints[2] = QPoint(600, 100);
    linePoints[3] = QPoint(600, 200);
    painter.drawPolyline(linePoints,4);

    //路径绘制
    QPainterPath path;     //QPainterPath为Qpainter类提供了一个存储容器，里面包含了画的内容和画的顺序，
    path.moveTo(50,150);    //当前位置移动到坐标50,150
    path.lineTo(350,150);   //当前位置开始画直线，终点位置坐标350,150
    path.lineTo(100,325);
    path.lineTo(200,50);
    path.lineTo(300,325);
    path.lineTo(50,150);

    pen->setColor(Qt::yellow);
    painter.setPen(*pen);
    painter.drawPath(path);

    pen->setColor(Qt::white);
    painter.setPen(*pen);
    //绘制文字
    painter.drawText(100, 200, 100, 80, Qt::AlignCenter,tr("Hello Qt!"));

    //绘制图片
    painter.drawPixmap(0,0,QPixmap("resources/gifts.png"));//绘制一个图像
}
//练习 绘制koch线
void Widget5::doExercise(){
    QPainter painter(this);
    pen->setColor(QColor(255, 255, 0));
    pen->setWidth(2);
    painter.setPen(*pen);
    painter.setBrush(*brush);

    QPoint p1(200, 300);
    QPoint p2(400, 300);
    QPoint p3(600, 300);
    p3 = xRotate(p2, p3, 120);

    QLine l1(p1, p2);
    QLine l2(p2,p3);
    QLine l3(p3,p1); //l1,l2,l3围成一个三角形
    int deep = 3;
    drawKochLines(l1, deep, painter);
    drawKochLines(l2, deep, painter);
    drawKochLines(l3, deep, painter);

}

//根据一条直线生成4条线段
QVector<QLine> Widget5::genarate(QLine &line){
    int dx = line.dx();
    int dy = line.dy();
    int x1 = line.p1().x();
    int y1 = line.p1().y();

    int x2 = line.p2().x();
    int y2 = line.p2().y();
    QPoint p1(x1, y1);
    QPoint p2(x1 + dx/3, y1 + dy/3);
    QPoint p4(x1 + dx*2/3, y1  + dy*2/3);
    QPoint p3 = yRotate(p2, p4, 60);
    QPoint p5(x2, y2);
    QVector<QLine> v;
    v.push_back(QLine(p1, p2));
    v.push_back(QLine(p2, p3));
    v.push_back(QLine(p3, p4));
    v.push_back(QLine(p4, p5));
    return v;

}
//绘制koch线 line:给定的直线， deep:递归深度
void Widget5::drawKochLines(QLine &line, int deep, QPainter & painter){

    QVector<QLine> v = genarate(line);

    for(QLine l : v){

        if(deep > 1){
            drawKochLines(l, deep-1, painter);
        }else{
            painter.drawLine(l);
        }
    }
}
//（向y轴方向旋转）旋转实现
QPoint Widget5::yRotate(const QPoint &centerPoint, const QPoint &rotatePoint, int angle){

    int x = (rotatePoint.x() - centerPoint.x()) * cos(angle * PI / 180)
            - (rotatePoint.y() - centerPoint.y()) * sin(angle * PI / 180)
            + centerPoint.x();

    int y = (rotatePoint.x() - centerPoint.x()) * sin(angle * PI / 180)
            + (rotatePoint.y() - centerPoint.y()) * cos(angle * PI / 180)
            + centerPoint.y();
    return QPoint(x, y);
}
//（向x轴方向旋转）旋转实现
QPoint Widget5::xRotate(const QPoint &centerPoint, const QPoint &rotatePoint, int angle){

    int x = (rotatePoint.x() - centerPoint.x()) * cos(angle * PI / 180)
            - (rotatePoint.y() - centerPoint.y()) * sin(angle * PI / 180)
            + centerPoint.x();

    int y = ((rotatePoint.y() - centerPoint.y()) * cos(angle * PI / 180))
            - ((rotatePoint.x() - centerPoint.x()) * sin(angle * PI / 180))
            + centerPoint.y();
    return QPoint(x, y);
}



